package webserver;

import lib4app.AbstractApp;
import lib4app.AppRemoteConnector;
import struct.SensorData;
import util.Util;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.*;
import io.netty.util.CharsetUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.PropertyConfigurator;

import java.io.File;
import java.net.InetSocketAddress;
import java.net.URI;
import java.util.List;
import java.util.Map;

public class HTTPServer {
    static {
        Util.configLog4j();
    }
    static final Log logger = LogFactory.getLog(HTTPServer.class);
    static AppRemoteConnector connector;

    public static void main(String[] args) throws Exception {
        connector = AppRemoteConnector.getInstance();
        connector.connectPlatform("127.0.0.1", 9090);
        if (connector.registerApp(new HttpApp())) {
            int port = 9092;
            ServerBootstrap serverBootstrap = new ServerBootstrap();

            EventLoopGroup bossGroup = new NioEventLoopGroup();
            EventLoopGroup workerGroup = new NioEventLoopGroup();

            serverBootstrap.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .localAddress(new InetSocketAddress(port))
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) {
                            ChannelPipeline pipeline = ch.pipeline();

                            // 添加HTTP请求解码器
                            pipeline.addLast(new HttpServerCodec());

                            // 添加自定义处理器
                            pipeline.addLast(new HTTPServerHandler());
                        }
                    });

            ChannelFuture channelFuture = serverBootstrap.bind(port).sync();
            logger.info("[HttpServer]: HTTP Server started on port " + port);

            channelFuture.channel().closeFuture().sync();
            bossGroup.shutdownGracefully().sync();
            workerGroup.shutdownGracefully().sync();
        }
    }

    static class HTTPServerHandler extends SimpleChannelInboundHandler<FullHttpRequest> {

        @Override
        protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) {
            // 获取请求方法和URI
            HttpMethod method = request.method();
            String uri = request.uri();
            logger.info("[HttpServer]: Received request, method: " + method + ", uri: " + uri);

            // 使用URI类解析路径名
            URI requestUri = URI.create(uri);
            String path = requestUri.getPath();

            // 解析查询参数
            QueryStringDecoder queryStringDecoder = new QueryStringDecoder(uri);
            Map<String, List<String>> queryParams = queryStringDecoder.parameters();

            // 处理不同的HTTP请求方法
            if (method.equals(HttpMethod.GET)) {
                // 处理GET请求
                handleGetRequest(ctx, path, queryParams);

            } else if (method.equals(HttpMethod.POST)) {
                // 处理POST请求
                handlePostRequest(ctx, path, request, queryParams);

            } else {
                // 其他请求方法暂不处理
                sendResponse(ctx, HttpResponseStatus.METHOD_NOT_ALLOWED, "Unsupported Method");
                return;
            }
        }

        private void handleGetRequest(ChannelHandlerContext ctx, String path, Map<String, List<String>> queryParams) {
            // 根据路径和查询参数生成响应内容
            String responseContent = "[HttpServer]: Get Request - Path: " + path + ", Query Params: " + queryParams.toString();
            logger.info(responseContent);
            // 发送响应
            sendResponse(ctx, HttpResponseStatus.OK, responseContent);
        }

        private void handlePostRequest(ChannelHandlerContext ctx, String path, FullHttpRequest request, Map<String, List<String>> queryParams) {
            // 解析请求体
            ByteBuf content = request.content();
            String requestBody = content.toString(CharsetUtil.UTF_8);

            // 根据路径、请求体和查询参数生成响应内容
            String responseContent = "[HttpServer]: Post Request - Path: " + path + ", Request Body: " + requestBody + ", Query Params: " + queryParams.toString();
            logger.info(responseContent);
            // 发送响应
            sendResponse(ctx, HttpResponseStatus.OK, responseContent);
        }

        private void sendResponse(ChannelHandlerContext ctx, HttpResponseStatus status, String content) {
            ByteBuf buffer = Unpooled.copiedBuffer(content, CharsetUtil.UTF_8);

            FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status, buffer);
            response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain");
            response.headers().set(HttpHeaderNames.CONTENT_LENGTH, buffer.readableBytes());

            // 添加以下这行来告知客户端关闭连接
            if (ctx.channel().isActive()) {
                response.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE);
            }

            ChannelFuture future = ctx.writeAndFlush(response);
            // 移除以下这行来保持连接
            // future.addListener(ChannelFutureListener.CLOSE);
        }
    }

    static class HttpApp extends AbstractApp {

        @Override
        public void getMsg(String sensorName, SensorData value) {

        }

        @Override
        public void configApp() {
            this.appName = "HttpServer";
            this.appDescription = "HttpServer";
        }
    }
}
